import { MutableRefObject, ReactText, Dispatch } from 'react';
import { extendApi, childSaveData } from '@inbiz/utils';
import type { CascaderProps } from './index';
import { IOptionType } from './type';

type fieldNames = {
  label: string;
  value: string;
  children: string;
};

interface IParams extends CascaderProps {
  value: ReactText[];
  options: IOptionType[];
  fieldNames: fieldNames;
  setOptions: Dispatch<React.SetStateAction<IOptionType[]>>;
}

const treeFind = (
  tree: IOptionType[],
  findKey: ReactText,
  fieldNames: fieldNames,
): IOptionType | null => {
  for (const data of tree) {
    if (data[fieldNames.value] === findKey) return data;
    if (data[fieldNames.children]) {
      const res = treeFind(data[fieldNames.children], findKey, fieldNames);
      if (res) return res;
    }
  }
  return null;
};

const flatOption = (options: Array<any>, result: Array<any> = []) => {
  let target = [...result];
  for (let i = 0; i < options.length; i++) {
    const current = options[i];
    target.push({
      ...current,
      child: null,
    });
    if (current.child && current.child.length > 0) {
      target = flatOption(current.child, target);
    }
  }
  return target;
};

export default extendApi(
  (_events: MutableRefObject<CascaderProps['callBackEvents']>, props: IParams) => {
    const { options, setOptions, fieldNames, value, multiple, configModalValue } = props;
    return {
      getData: () => options,
      getText: (data?: []) => {
        let submitData = multiple
        ?  props.value?.map((item) => item?.slice(-1))
        :  props.value.slice(-1);

        const flatenList = flatOption(data || options);
        const label = (fieldNames['label']?.split('$') ?? [])[1];
        const valueField = (fieldNames['value']?.split('$') ?? [])[1];
        return flatenList
        .filter((ele) => submitData.some((child) => `${ele[valueField]}` === `${child}`))
        .map((ele) => ele[label])
        .join(',');
      },
      loadData: (data: IOptionType[]) => data && setOptions(data),
      getSaveData: () => {
        //@ts-ignore
        const submitData = multiple
          ? props.value?.map((item) => item.slice(-1))
          : props.value?.slice(-1);
        let result: any;
        let currentIdField = configModalValue?.currentIdField || '';
        if (currentIdField.includes('$')) {
          currentIdField = currentIdField.split('$')[1];
        }
        try {
          result = childSaveData({
            nextValue: submitData ?? [],
            options,
            storageConfig: props.storageConfig,
            currentIdField,
          });
        } catch (err) {
          console.log(err);
        }

        return {
          value: submitData.join(','),
          //@ts-ignore
          childData:
            props.storageConfig && props.childModelConfig
              ? {
                  // deleteValues,
                  controlId: props.controlId,
                  modelKey: props.storageConfig?.business,
                  datas: result,
                }
              : undefined,
        };
      },
    };
  },
);
